{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "symbol = 'Security 1'\n",
    "symbol2 = 'Security 2'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "price_data = pd.DataFrame(np.cumsum(np.random.randn(150, 2).dot([[0.5, 0.4], [0.4, 1.0]]), axis=0) + 100,\n",
    "                          columns=['Security 1', 'Security 2'],\n",
    "                          index=pd.date_range(start='01-01-2007', periods=150))\n",
    "\n",
    "dates_actual = price_data.index.values\n",
    "prices = price_data[symbol].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bqplot import DateScale, LinearScale, Axis, Lines, Scatter, Bars, Hist, Figure\n",
    "from bqplot.interacts import (\n",
    "    FastIntervalSelector, IndexSelector, BrushIntervalSelector,\n",
    "    BrushSelector, MultiSelector, LassoSelector, PanZoom, HandDraw\n",
    ")\n",
    "from traitlets import link\n",
    "\n",
    "from ipywidgets import ToggleButtons, VBox, HTML"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Line Chart Selectors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fast Interval Selector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## First we define a Figure\n",
    "dt_x_fast = DateScale()\n",
    "lin_y = LinearScale()\n",
    "\n",
    "x_ax = Axis(label='Index', scale=dt_x_fast)\n",
    "x_ay = Axis(label=(symbol + ' Price'), scale=lin_y, orientation='vertical')\n",
    "lc = Lines(x=dates_actual, y=prices, scales={'x': dt_x_fast, 'y': lin_y}, colors=['orange'])\n",
    "lc_2 = Lines(x=dates_actual[50:], y=prices[50:] + 2, scales={'x': dt_x_fast, 'y': lin_y}, colors=['blue'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Next we define the type of selector we would like\n",
    "intsel_fast = FastIntervalSelector(scale=dt_x_fast, marks=[lc, lc_2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Now, we define a function that will be called when the FastIntervalSelector is interacted with\n",
    "def fast_interval_change_callback(change):\n",
    "    db_fast.value = 'The selected period is ' + str(change.new)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Now we connect the selectors to that function\n",
    "intsel_fast.observe(fast_interval_change_callback, names=['selected'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## We use the HTML widget to see the value of what we are selecting and modify it when an interaction is performed\n",
    "## on the selector\n",
    "db_fast = HTML()\n",
    "db_fast.value = 'The selected period is ' + str(intsel_fast.selected)\n",
    "\n",
    "fig_fast_intsel = Figure(marks=[lc, lc_2], axes=[x_ax, x_ay], title='Fast Interval Selector Example',\n",
    "                         interaction=intsel_fast) #This is where we assign the interaction to this particular Figure\n",
    "\n",
    "VBox([db_fast, fig_fast_intsel])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Index Selector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "db_index = HTML(value='[]')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Now we try a selector made to select all the y-values associated with a single x-value\n",
    "index_sel = IndexSelector(scale=dt_x_fast, marks=[lc, lc_2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Now, we define a function that will be called when the selectors are interacted with\n",
    "def index_change_callback(change):\n",
    "    db_index.value = 'The selected date is ' + str(change.new)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "index_sel.observe(index_change_callback, names=['selected'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig_index_sel = Figure(marks=[lc, lc_2], axes=[x_ax, x_ay], title='Index Selector Example',\n",
    "                       interaction=index_sel)\n",
    "VBox([db_index, fig_index_sel])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Returning indexes of selected values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime as py_dtime\n",
    "\n",
    "dt_x_index = DateScale(min=np.datetime64(py_dtime(2006, 6, 1)))\n",
    "lin_y2 = LinearScale()\n",
    "\n",
    "lc2_index = Lines(x=dates_actual, y=prices,\n",
    "            scales={'x': dt_x_index, 'y': lin_y2})\n",
    "\n",
    "x_ax1 = Axis(label='Date', scale=dt_x_index)\n",
    "x_ay2 = Axis(label=(symbol + ' Price'), scale=lin_y2, orientation='vertical')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "intsel_date = FastIntervalSelector(scale=dt_x_index, marks=[lc2_index])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "db_date = HTML()\n",
    "db_date.value = str(intsel_date.selected)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Now, we define a function that will be called when the selectors are interacted with - a callback\n",
    "def date_interval_change_callback(change):\n",
    "    db_date.value = str(change.new)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Notice here that we call the observe on the Mark lc2_index rather than on the selector intsel_date\n",
    "lc2_index.observe(date_interval_change_callback, names=['selected'])\n",
    "\n",
    "fig_date_mark = Figure(marks=[lc2_index], axes=[x_ax1, x_ay2],\n",
    "                       title='Fast Interval Selector Selected Indices Example', interaction=intsel_date)\n",
    "\n",
    "VBox([db_date, fig_date_mark])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Brush Selector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### We can do the same with any type of selector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Defining a new Figure\n",
    "dt_x_brush = DateScale(min=np.datetime64(py_dtime(2006, 6, 1)))\n",
    "lin_y2_brush = LinearScale()\n",
    "\n",
    "lc3_brush = Lines(x=dates_actual, y=prices,\n",
    "            scales={'x': dt_x_brush, 'y': lin_y2_brush})\n",
    "\n",
    "x_ax_brush = Axis(label='Date', scale=dt_x_brush)\n",
    "x_ay_brush = Axis(label=(symbol + ' Price'), scale=lin_y2_brush, orientation='vertical')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "db_brush = HTML(value='[]')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "brushsel_date = BrushIntervalSelector(scale=dt_x_brush, marks=[lc3_brush], color='FireBrick')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Now, we define a function that will be called when the selectors are interacted with - a callback\n",
    "def date_brush_change_callback(change):\n",
    "    db_brush.value = str(change.new)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lc3_brush.observe(date_brush_change_callback, names=['selected'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig_brush_sel = Figure(marks=[lc3_brush], axes=[x_ax_brush, x_ay_brush],\n",
    "                       title='Brush Selector Selected Indices Example', interaction=brushsel_date)\n",
    "\n",
    "VBox([db_brush, fig_brush_sel])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Scatter Chart Selectors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Brush Selector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "date_fmt = '%m-%d-%Y'\n",
    "\n",
    "sec2_data = price_data[symbol2].values\n",
    "dates = price_data.index.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sc_x = LinearScale()\n",
    "sc_y = LinearScale()\n",
    "\n",
    "scatt = Scatter(x=prices, y=sec2_data,\n",
    "                scales={'x': sc_x, 'y': sc_y})\n",
    "\n",
    "sc_xax = Axis(label=(symbol), scale=sc_x)\n",
    "sc_yax = Axis(label=(symbol2), scale=sc_y, orientation='vertical')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "br_sel = BrushSelector(x_scale=sc_x, y_scale=sc_y, marks=[scatt], color='red')\n",
    "\n",
    "db_scat_brush = HTML(value='[]')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## call back for the selector\n",
    "def brush_callback(change):\n",
    "    db_scat_brush.value = str(br_sel.selected)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "br_sel.observe(brush_callback, names=['brushing'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig_scat_brush = Figure(marks=[scatt], axes=[sc_xax, sc_yax], title='Scatter Chart Brush Selector Example',\n",
    "                        interaction=br_sel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "VBox([db_scat_brush, fig_scat_brush])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Brush Selector with Date Values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sc_brush_dt_x = DateScale(date_format=date_fmt)\n",
    "sc_brush_dt_y = LinearScale()\n",
    "\n",
    "scatt2 = Scatter(x=dates_actual, y=sec2_data,\n",
    "                scales={'x': sc_brush_dt_x, 'y': sc_brush_dt_y})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "br_sel_dt = BrushSelector(x_scale=sc_brush_dt_x, y_scale=sc_brush_dt_y, marks=[scatt2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "db_brush_dt = HTML(value=str(br_sel_dt.selected))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## call back for the selector\n",
    "def brush_dt_callback(change):\n",
    "    db_brush_dt.value = str(br_sel_dt.selected)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "br_sel_dt.observe(brush_dt_callback, names=['brushing'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sc_xax = Axis(label=(symbol), scale=sc_brush_dt_x)\n",
    "sc_yax = Axis(label=(symbol2), scale=sc_brush_dt_y, orientation='vertical')\n",
    "fig_brush_dt = Figure(marks =[scatt2], axes=[sc_xax, sc_yax], title='Brush Selector with Dates Example',\n",
    "                      interaction=br_sel_dt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "VBox([db_brush_dt, fig_brush_dt])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Histogram Selectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## call back for selectors\n",
    "def interval_change_callback(name, value):\n",
    "    db3.value = str(value)\n",
    "    \n",
    "## call back for the selector\n",
    "def brush_callback(change):\n",
    "    if(not br_intsel.brushing):\n",
    "        db3.value = str(br_intsel.selected)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "returns = np.log(prices[1:]) - np.log(prices[:-1])\n",
    "hist_x = LinearScale()\n",
    "hist_y = LinearScale()\n",
    "hist = Hist(sample=returns, scales={'sample': hist_x, 'count': hist_y})\n",
    "\n",
    "br_intsel = BrushIntervalSelector(scale=hist_x, marks=[hist])\n",
    "br_intsel.observe(brush_callback, names=['selected'])\n",
    "br_intsel.observe(brush_callback, names=['brushing'])\n",
    "\n",
    "db3 = HTML()\n",
    "db3.value = str(br_intsel.selected)\n",
    "\n",
    "h_xax = Axis(scale=hist_x, label='Returns', grids='off', set_ticks=True, tick_format='0.2%')\n",
    "h_yax = Axis(scale=hist_y, label='Freq', orientation='vertical', grid_lines='none')\n",
    "\n",
    "fig_hist = Figure(marks=[hist], axes=[h_xax, h_yax], title='Histogram Selection Example', interaction=br_intsel)\n",
    "VBox([db3, fig_hist])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi Selector\n",
    "\n",
    "* This selector provides the ability to have multiple brush selectors on the same graph.\n",
    "* The first brush works like a regular brush.\n",
    "* `Ctrl + click` creates a new brush, which works like the regular brush. \n",
    "* The `active` brush has a Green border while all the `inactive` brushes have a Red border.\n",
    "* `Shift + click` deactivates the current `active` brush. Now, click on any `inactive` brush to make it `active`.\n",
    "* `Ctrl + Alt + Shift + click` clears and resets all the brushes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def multi_sel_callback(change):\n",
    "    if(not multi_sel.brushing):\n",
    "        db4.value = str(multi_sel.selected)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line_x = LinearScale()\n",
    "line_y = LinearScale()\n",
    "line = Lines(x=np.arange(100), y=np.random.randn(100), scales={'x': line_x, 'y': line_y})\n",
    "\n",
    "multi_sel = MultiSelector(scale=line_x, marks=[line])\n",
    "multi_sel.observe(multi_sel_callback, names=['selected'])\n",
    "multi_sel.observe(multi_sel_callback, names=['brushing'])\n",
    "\n",
    "db4 = HTML()\n",
    "db4.value = str(multi_sel.selected)\n",
    "\n",
    "h_xax = Axis(scale=line_x, label='Returns', grid_lines='none')\n",
    "h_yax = Axis(scale=hist_y, label='Freq', orientation='vertical', grid_lines='none')\n",
    "\n",
    "fig_multi = Figure(marks=[line], axes=[h_xax, h_yax], title='Multi-Selector Example',\n",
    "                   interaction=multi_sel)\n",
    "VBox([db4, fig_multi])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# changing the names of the intervals.\n",
    "multi_sel.names = ['int1', 'int2', 'int3']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi Selector with Date X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def multi_sel_dt_callback(change):\n",
    "    if(not multi_sel_dt.brushing):\n",
    "        db_multi_dt.value = str(multi_sel_dt.selected)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line_dt_x = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))\n",
    "line_dt_y = LinearScale()\n",
    "line_dt = Lines(x=dates_actual, y=sec2_data, scales={'x': line_dt_x, 'y': line_dt_y}, colors=['red'])\n",
    "\n",
    "multi_sel_dt = MultiSelector(scale=line_dt_x)\n",
    "multi_sel_dt.observe(multi_sel_dt_callback, names=['selected'])\n",
    "multi_sel_dt.observe(multi_sel_dt_callback, names=['brushing'])\n",
    "\n",
    "db_multi_dt = HTML()\n",
    "db_multi_dt.value = str(multi_sel_dt.selected)\n",
    "\n",
    "h_xax_dt = Axis(scale=line_dt_x, label='Returns', grid_lines='none')\n",
    "h_yax_dt = Axis(scale=line_dt_y, label='Freq', orientation='vertical', grid_lines='none')\n",
    "\n",
    "fig_multi_dt = Figure(marks=[line_dt], axes=[h_xax_dt, h_yax_dt], title='Multi-Selector with Date Example',\n",
    "                      interaction=multi_sel_dt)\n",
    "VBox([db_multi_dt, fig_multi_dt])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lasso Selector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lasso_sel = LassoSelector()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xs, ys = LinearScale(), LinearScale()\n",
    "data = np.arange(20)\n",
    "line_lasso = Lines(x=data, y=data, scales={'x': xs, 'y': ys})\n",
    "scatter_lasso = Scatter(x=data, y=data, scales={'x': xs, 'y': ys}, colors=['skyblue'])\n",
    "bar_lasso = Bars(x=data, y=data/2., scales={'x': xs, 'y': ys})\n",
    "xax_lasso, yax_lasso = Axis(scale=xs, label='X'), Axis(scale=ys, label='Y', orientation='vertical')\n",
    "fig_lasso = Figure(marks=[scatter_lasso, line_lasso, bar_lasso], axes=[xax_lasso, yax_lasso],\n",
    "                   title='Lasso Selector Example', interaction=lasso_sel)\n",
    "lasso_sel.marks = [scatter_lasso, line_lasso]\n",
    "fig_lasso"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scatter_lasso.selected, line_lasso.selected"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Pan Zoom"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xs_pz = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))\n",
    "ys_pz = LinearScale()\n",
    "line_pz = Lines(x=dates_actual, y=sec2_data, scales={'x': xs_pz, 'y': ys_pz}, colors=['red'])\n",
    "\n",
    "panzoom = PanZoom(scales={'x': [xs_pz], 'y': [ys_pz]})\n",
    "xax = Axis(scale=xs_pz, label='Date', grids='off')\n",
    "yax = Axis(scale=ys_pz, label='Price', orientation='vertical', grid_lines='none')\n",
    "\n",
    "Figure(marks=[line_pz], axes=[xax, yax], interaction=panzoom)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hand Draw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xs_hd = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))\n",
    "ys_hd = LinearScale()\n",
    "line_hd = Lines(x=dates_actual, y=sec2_data, scales={'x': xs_hd, 'y': ys_hd}, colors=['red'])\n",
    "\n",
    "handdraw = HandDraw(lines=line_hd)\n",
    "xax = Axis(scale=xs_hd, label='Date', grid_lines='none')\n",
    "yax = Axis(scale=ys_hd, label='Price', orientation='vertical', grid_lines='none')\n",
    "\n",
    "Figure(marks=[line_hd], axes=[xax, yax], interaction=handdraw)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Unified Figure with All Interactions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dt_x = DateScale(date_format=date_fmt, min=py_dtime(2007, 1, 1))\n",
    "lc1_x = LinearScale()\n",
    "lc2_y = LinearScale()\n",
    "\n",
    "lc2 = Lines(x=np.linspace(0.0, 10.0, len(prices)), y=prices * 0.25,\n",
    "            scales={'x': lc1_x, 'y': lc2_y}, \n",
    "            display_legend=True,\n",
    "            labels=['Security 1'])\n",
    "\n",
    "lc3 = Lines(x=dates_actual, y=sec2_data,\n",
    "            scales={'x': dt_x, 'y': lc2_y},\n",
    "            colors=['red'], \n",
    "            display_legend=True, \n",
    "            labels=['Security 2'])\n",
    "\n",
    "lc4 = Lines(x=np.linspace(0.0, 10.0, len(prices)), y=sec2_data * 0.75,\n",
    "            scales={'x': LinearScale(min=5, max=10), 'y': lc2_y},\n",
    "            colors=['green'], display_legend=True, \n",
    "            labels=['Security 2 squared'])\n",
    "\n",
    "x_ax1 = Axis(label='Date', scale=dt_x)\n",
    "x_ax2 = Axis(label='Time', scale=lc1_x, side='top', grid_lines='none')\n",
    "x_ay2 = Axis(label=(symbol + ' Price'), scale=lc2_y, orientation='vertical')\n",
    "\n",
    "\n",
    "fig = Figure(marks=[lc2, lc3, lc4], axes=[x_ax1, x_ax2, x_ay2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## declaring the interactions\n",
    "multi_sel = MultiSelector(scale=dt_x, marks=[lc2, lc3])\n",
    "br_intsel = BrushIntervalSelector(scale=lc1_x, marks=[lc2, lc3])\n",
    "index_sel = IndexSelector(scale=dt_x, marks=[lc2, lc3])\n",
    "int_sel = FastIntervalSelector(scale=dt_x, marks=[lc3, lc2])\n",
    "\n",
    "hd = HandDraw(lines=lc2)\n",
    "hd2 = HandDraw(lines=lc3)\n",
    "pz = PanZoom(scales={'x': [dt_x], 'y': [lc2_y]})\n",
    "\n",
    "deb = HTML()\n",
    "deb.value = '[]'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Call back handler for the interactions\n",
    "def test_callback(change):\n",
    "    deb.value = str(change.new)\n",
    "    \n",
    "multi_sel.observe(test_callback, names=['selected'])\n",
    "br_intsel.observe(test_callback, names=['selected'])\n",
    "index_sel.observe(test_callback, names=['selected'])\n",
    "int_sel.observe(test_callback, names=['selected'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import OrderedDict\n",
    "selection_interacts = ToggleButtons(options=OrderedDict([('HandDraw1', hd), ('HandDraw2', hd2), ('PanZoom', pz), \n",
    "                                                       ('FastIntervalSelector', int_sel), ('IndexSelector', index_sel),\n",
    "                                                       ('BrushIntervalSelector', br_intsel), ('MultiSelector', multi_sel),\n",
    "                                                       ('None', None)]))\n",
    "\n",
    "link((selection_interacts, 'value'), (fig, 'interaction'))\n",
    "VBox([deb, fig, selection_interacts], align_self='stretch')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set the scales of lc4 to the ones of lc2 and check if panzoom pans the two.\n",
    "lc4.scales = lc2.scales"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
